#ifndef __SYSTEM_MEM_BUFFER_H__
#define __SYSTEM_MEM_BUFFER_H__

#pragma once

#include "NezhaRefable.h"
#include "NezhaPointer.h"

namespace Nezha
{
	/** just a local memory buffer object. */
	class FOUNDATION_ENTRY SystemMemBuffer : public Refable
	{
	public:
		SystemMemBuffer();
		virtual ~SystemMemBuffer();

		/**
		@return
			actual bytes read.
		*/
		u32 read(SystemMemBuffer* buf, u32 length, u32 offset = 0) const;

		/**
		@return
			actual bytes read.
		*/
		u32 read(SystemMemBuffer* buf, u32 bufOffset, u32 length, u32 offset = 0) const;

		/**
		@return
			actual bytes read.
		*/
		u32 read(u8* buf, u32 length, u32 offset = 0) const;

		/** append data from buf.
		@return
			length of new buffer.
		*/
		u32 extendBuffer(SystemMemBuffer* buf);

		/** append data from buf.
		@return
			length of new buffer.
		*/
		u32 extendBuffer(u8* data, u32 length);

		/**
		@return
			actual bytes wrote.
		*/
		u32 write(u8* data, u32 length, u32 offset = 0);

		u32 sizeInBytes() const
		{
			return mSizeInBytes;
		}

		/** clone the buffer. */
		SystemMemBuffer* clone() const;

		void* data()
		{
			return mData;
		}

		void resize(u32 sizeInBytes);
	private:
		SystemMemBuffer& operator = (const SystemMemBuffer& rb);

		u8* mData;
		u32 mSizeInBytes;
	};

	typedef RefCountedPtr<SystemMemBuffer>::Default SystemMemBufferPtr;

	/** for buffer object sharing. */
	class FOUNDATION_ENTRY SystemMemBufferShared
	{
	public:
		SystemMemBufferShared();
		SystemMemBufferShared(u32 offset, u32 sizeInBytes, const SystemMemBufferPtr& buf);
		~SystemMemBufferShared();

		u32 getLength() const
		{
			return mLengthInBytes;
		}

		void* getData()
		{
			return mSysMemBuffer.isNull() ? NULL : (void*)(((u8*)mSysMemBuffer->data()) + mOffset);
		}

		u32 write(u8* data, u32 length, u32 offset = 0);

		/** reset. */
		void reset(u32 offset, u32 sizeInBytes, const SystemMemBufferPtr& buf);

	protected:
		u32 mOffset;
		u32 mLengthInBytes;
		SystemMemBufferPtr mSysMemBuffer;
	};


}//end namespace Nezha

#endif //end __SYSTEM_MEM_BUFFER_H__